#ifndef __TAB_COMM_H__
#define __TAB_COMM_H__ 1

#include <QMutex>
#include <QObject>
#include <QWidget>
#include <QVBoxLayout>
#include <QPlainTextEdit>
#include <QProgressBar>
#include <QLabel>
#include <QHBoxLayout>
#include <QLineEdit>
#include <QPushButton>
#include <QFrame>
#include <QGroupBox>
#include <QGridLayout>

class CTabComm : public QWidget
{
	Q_OBJECT

public:
	CTabComm(QWidget* pParent = 0);
	virtual ~CTabComm();

	void resetCounters();
	void resetInfoLabels();

signals:
	void protocolReadDataSend(const void*, int);

private slots:
	void chatButtonClicked();

	void extractBufferInfoReceived(quint32 pUsed, quint32 pSize);
	void frameSendLengthReceived(quint32 pLength);
	void frameRecvLengthReceived(quint32 pLength, bool pError);
	void packetSendLengthReceived(quint32 pLength);
	void packetRecvLengthReceived(quint32 pLength, bool pCrcError);
	void streamSendInfoReceived(int pId, int pAck, quint32 pLength, bool pReplay);
	void streamSendDataReceived(void* pData, int pLength);
	void streamRecvInfoReceived(int pId, int pAck, quint32 pLength, bool pReplay);
	void streamRecvDataReceived(void* pData, int pLength);
	void protocolWriteDataReceived(void* pData, int pLength);
	void protocolReadFeedbackReceived(quint32 pRead, quint32 pSize);
	void embedAmpReceived(quint8 pAmp);
	void extractAmpReceived(quint8 pAmp);

private:
	CTabComm(const CTabComm& );
	CTabComm& operator=(const CTabComm& );

	static const uint sStreamDataShowCount;

	enum EProtocolStatus
	{
		STAT_NONE = 0,
		STAT_NEW_CHAT_OR_FILE,
		STAT_CHAT,
	};

	EProtocolStatus mProtocolStat;
	unsigned int mChatLength;
	unsigned int mChatIndex;
	QString mChatMessage;
	QMutex mChatAppendSync;

	QVBoxLayout mSections;

	QLabel mChatRecvInfoLabel;
	QPlainTextEdit* mChatWindow;
	QHBoxLayout mChatEditLine;
	QLineEdit mChatEdit;
	QPushButton mChatButton;

	QFrame mSeperator;

	QHBoxLayout mStreamLine;
	QGroupBox mStreamSendBox;
	QVBoxLayout mStreamSendLayout;
	QLabel mStreamSendLabel;
	QGridLayout mStreamSendDataGrid;
	QLabel*** mStreamSendData;
	QGroupBox mStreamRecvBox;
	QVBoxLayout mStreamRecvLayout;
	QLabel mStreamRecvLabel;
	QGridLayout mStreamRecvDataGrid;
	QLabel*** mStreamRecvData;

	QHBoxLayout mPacketLine;
	QGroupBox mPacketSendBox;
	QHBoxLayout mPacketSendLayout;
	QLabel mPacketSendLabel;
	QGroupBox mPacketRecvBox;
	QHBoxLayout mPacketRecvLayout;
	QLabel mPacketRecvLabel;

	QHBoxLayout mFrameLine;
	QGroupBox mFrameSendBox;
	QHBoxLayout mFrameSendLayout;
	QLabel mFrameSendLabel;
	QGroupBox mFrameRecvBox;
	QHBoxLayout mFrameRecvLayout;
	QLabel mFrameRecvLabel;

	QHBoxLayout mAmpLine;
	QProgressBar mAmpEmbed;
	QProgressBar mAmpExtract;

	QHBoxLayout mBufferLine;
	QLabel mBufferLabel;
	QProgressBar mBufferProgressBar;

	ulong mStreamPayloadSendCount;
	uint mStreamSendByteCount;
	ulong mStreamPayloadRecvCount;
	uint mStreamRecvByteCount;
	int mPacketSendCountGood;
	int mPacketSendCount;
	ulong mPayloadSendCount;
	int mPacketRecvCountGood;
	int mPacketRecvCount;
	ulong mPayloadRecvCount;
	int mFrameSendCount;
	int mFrameRecvCount;

	void setupUiElements();
	void setupActions();

	QString updateStreamInfo(ulong& pPayloadCount, int pId, int pAck, quint32 pPayloadLength, bool pReplay = false);
	void updateStreamData(QLabel***& pStreamData, uint& pStreamByteCount, void* pData, int pLength);
	/**
	 * @param pCrcError -1 for wrong CRC, 0 for hidden and 1 for correct CRC
	 */
	QString updatePacketInfo(int& pPacketCountGood, int& pPacketCount, ulong& pPayloadCount, quint32 pPayloadLength, int pCrcError = 0);
	QString updateFrameInfo(int& pFrameCount, quint32 pFrameLength, bool pError = false);
};

#endif /* __TAB_COMM_H__ */

